
#include "User_App.h"
#include "bsp_port.h"
#include "bsp_PWM.h"
#include "bsp_Timer.h"
#include "stdint.h"
#include "modbus.h"
#include "u_Task.h"

bsp_TIM_t Ti_RUN_LED;
bsp_TIM_t Ti_BEEP;
bsp_TIM_t Ti_Info;
bsp_TIM_t Ti_Heat_Tim; // 加热时间基准1s

PWM_t PWM_BEEP;

mcu_info_t info;

Modbus_t modbus = {0};
uint8_t ModbusDataBuf[256];

void bsp_Set_Beep(uint8_t num);
void Ti_RUN_LED_event(void);
void Ti_BEEP_event(void);
void Ti_Info_event(void);
void Ti_Heat_Tim_event(void);

static void MB_SendData(uint8_t *data, uint16_t datalen);
static MB_ERR_Typedef ModbusWriteReg(uint16_t StartAddr, uint16_t *data, uint16_t Datalen);
static MB_ERR_Typedef ModbusReadReg(uint16_t StartAddr, uint16_t *data, uint16_t Datalen);

void User_App(void)
{
#if 0

    // LED_Run_Debug();
    // bsp_PWM_Debug();
    // bsp_Ti_Debug();
    u_Task_Debug();

#else

    Ti_obj_New(&Ti_RUN_LED, 500, Ti_RUN, Ti_RUN_LED_event);
    Ti_obj_New(&Ti_BEEP, 80, Ti_STOP, Ti_BEEP_event);
    Ti_obj_New(&Ti_Info, 300, Ti_RUN, Ti_Info_event);
    Ti_obj_New(&Ti_Heat_Tim, 1000, Ti_STOP, Ti_Heat_Tim_event);

    PWM_BEEP = bsp_PWM_Obj_New(PWM_BEEP_GPIO, 2700, 50, p_STOP);
    bsp_Set_Beep(2 * 2 + 1); // 蜂鸣两声
    bsp_Task_Obj_New(&HeatWater);

    MB_SetLocalAddr(&modbus, 0x01);
    MB_SetBuad(&modbus, 9600);
    MB_AddSendBytes(&modbus, MB_SendData);                                    // 添加串口发送函数
    MB_AddGetTimestamp(&modbus, get_Timestampus);                             // 添加定时获取时间，防止超时
    MB_SetReadRegs_UserFun(&modbus, ModbusReadReg);                           // 设置用户读取函数
    MB_SetWriteRegs_UserFun(&modbus, ModbusWriteReg);                         // 设置用户写入函数
    MB_AddRxDataBuf(&modbus, (uint32_t)ModbusDataBuf, sizeof(ModbusDataBuf)); // 添加接收缓存

    while (1)
    {
        Modbus_Parse(&modbus); // modbus
        bsp_Ti_All_Handle();
        bsp_Task_Handle();
        bsp_IWDG_ReloadCounter();
    }
#endif
}

void LED_Run_Debug(void)
{
    while (1)
    {
        LED_RUN_TOGG;
        LL_mDelay(500);
    }
}
void bsp_Set_Beep(uint8_t num)
{
    Ti_obj_Set_Count(&Ti_BEEP, num);
    Ti_obj_Set_Run(&Ti_BEEP);
}

void Ti_RUN_LED_event(void)
{
    // uint8_t timebuff[2] = {0x22, 0x55};
    //  static uint8_t tem = 0;
    // 添加需要执行的程序
    // printf("hedddd\n");
    // bsp_USART1_SendBytes(timebuff, 2);

    LED_RUN_TOGG;
    // if (tem == 0)
    // {
    //   bsp_Ctrl_Water_Valve(s_OPEN);
    //   bsp_Ctrl_Heat_Switch(s_OPEN);
    //   tem = 1;
    // }
    // else
    // {
    //   bsp_Ctrl_Water_Valve(s_CLOSE);
    //   bsp_Ctrl_Heat_Switch(s_CLOSE);

    //   tem = 0;
    // }
}
void Ti_BEEP_event(void)
{

    if (Ti_obj_Get_Count(&Ti_BEEP) == 0)
    {
        bsp_PWM_Set_Stop(&PWM_BEEP);
        return;
    }
    printf("BEEP:%d\n", bsp_PWM_Get_State(&PWM_BEEP));

    if (bsp_PWM_Get_State(&PWM_BEEP) == p_STOP)
    {
        bsp_PWM_Set_Run(&PWM_BEEP);
    }
    else
    {
        bsp_PWM_Set_Stop(&PWM_BEEP);
    }
}
void Ti_Info_event(void)
{
    info.m_KettleFlag = bsp_Get_Kettle_State();
    info.m_SpillFlag = bsp_Get_Spill_State();
}
void Ti_Heat_Tim_event(void)
{
    if (info.m_Now_Heat_Tim > 0)
        info.m_Now_Heat_Tim--;
}
// 串口发生函数
static void MB_SendData(uint8_t *data, uint16_t datalen)
{
    bsp_USART1_SendBytes(data, datalen);
}
static MB_ERR_Typedef ModbusWriteReg(uint16_t StartAddr, uint16_t *data, uint16_t Datalen)
{
    uint16_t Reg_Index = 0;
    while (Reg_Index < Datalen)
    {
        switch (StartAddr + Reg_Index)
        {
        case MB_W_HEAT_START:
        {
            // mb_Value = data[0];
            info.m_Set_Heat_Tim = data[0] >> 8;
            info.m_Set_Water_Volume = (data[0] & 0xFF) * 10;
            bsp_Task_Obj_Set_Run(&HeatWater);
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_W_HEAT_STOP:
        {
            // mb_Value = data[0];
            bsp_Task_Obj_Set_Stop(&HeatWater);
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_RW_HEAT_SWITCH:
        {
            // mb_Value = data[0];
            if (data[0] == 1)
            {
                bsp_Ctrl_Heat_Switch(s_OPEN);
            }
            else
            {
                bsp_Ctrl_Heat_Switch(s_CLOSE);
            }
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_RW_WATER_VALVE:
        {
            // mb_Value = data[0];
            if (data[0] == 1)
            {
                bsp_Ctrl_Water_Valve(s_OPEN);
            }
            else
            {
                bsp_Ctrl_Water_Valve(s_CLOSE);
            }
        }
            Reg_Index += 1;
            data += 1;
            break;
        default:
            return MB_DATA_ADDR_ERR;
        }
    }
    return MB_OK;
}
static MB_ERR_Typedef ModbusReadReg(uint16_t StartAddr, uint16_t *data, uint16_t Datalen)
{
    uint16_t Reg_Index = 0;
    while (Reg_Index < Datalen)
    {
        switch (StartAddr + Reg_Index)
        {
        case MB_R_HEARTBEAT: // 心跳
        {
            data[0] = 0x55aa;
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_R_HEAT_STATE: // 加热程序状态
        {
            data[0] = 100;
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_RW_HEAT_SWITCH: // 加热开关
        {
            data[0] = bsp_Get_Heat_Switch();
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_RW_WATER_VALVE: // 进水阀门
        {
            data[0] = bsp_Get_Water_Valve();
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_R_KETTLE_STATE: // 水壶状态
        {
            data[0] = bsp_Get_Kettle_State();
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_R_SPILL_STATE: // 水溢出状态
        {
            data[0] = bsp_Get_Spill_State();
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_R_HEAT_TIM: // 剩余加热时间
        {
            data[0] = info.m_Now_Heat_Tim;
        }
            Reg_Index += 1;
            data += 1;
            break;
        case MB_R_WATER_VALUE: // 剩余水量
        {
            data[0] = info.m_Now_Water_Volume;
        }
            Reg_Index += 1;
            data += 1;
            break;
        default:
            return MB_DATA_ADDR_ERR;
        }
    }
    return MB_OK;
}
